package com.qfedu.fmmall.service.impl;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.fmmall.common.status.ResStatus;
import com.qfedu.fmmall.common.vo.ResultVO;
import com.qfedu.fmmall.dao.IndexImgMapper;
import com.qfedu.fmmall.entity.IndexImg;
import com.qfedu.fmmall.service.IndexImgService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author : yanBin
 * @date :2021/12/14 14:12
 */
@Service
public class IndexImgServiceImpl implements IndexImgService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private IndexImgMapper indexImgMapper;

    private ObjectMapper objectMapper = new ObjectMapper();

    public ResultVO listIndexImg() {
        List<IndexImg> indexImgs = null;
        try {
            //查询redis
            String indexImgString = stringRedisTemplate.boundValueOps("indexImgs").get();

            //停顿3秒
            Thread.sleep(3000);

            if (StringUtils.isNotEmpty(indexImgString)) {
                JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, IndexImg.class);
                indexImgs = objectMapper.readValue(indexImgString, javaType);
            } else {
                //双从检测锁。应对redis击穿
                synchronized (this){
                    //1000个一样的请求加锁排队，第一次请求数据库。剩余请求redis
                    String indexImg1= stringRedisTemplate.boundValueOps("indexImgs").get();
                    if (StringUtils.isEmpty(indexImg1)){
                        indexImgs = indexImgMapper.listIndexImg();
                        if (!CollectionUtils.isEmpty(indexImgs)){
                            //写入redis并写入过期时间
                            String indexImgSting = objectMapper.writeValueAsString(indexImgs);
                            stringRedisTemplate.boundValueOps("indexImgs").set(indexImgSting,1,TimeUnit.DAYS);
                        }else {
                            //应对redis穿透。如果数据库查询为null则在redis储存空对象
                            List<IndexImg> ass = new ArrayList<>();
                            String s = objectMapper.writeValueAsString(ass);
                            stringRedisTemplate.boundValueOps("indexImgs").set(s,10,TimeUnit.SECONDS);
                        }

                    }else {
                        System.out.println("======================================="+"第二次访问数据库");
                        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, IndexImg.class);
                        indexImgs = objectMapper.readValue(indexImgString, javaType);
                    }

                }


            }

            return new ResultVO(ResStatus.OK.getCode(), "查询轮播图成功", indexImgs);
        } catch (Exception e) {
            return new ResultVO(ResStatus.NO.getCode(), e.getLocalizedMessage(), null);
        }

    }
}
